﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.ServerApi;
using TencentCloudOcrPlugin.Exception;

namespace TencentCloudOcrPlugin.Api
{
    public static class ApiHelper
    {
        private static readonly HashSet<string> OcrFileExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
        {
            ".jpg", ".jpeg", ".png", ".bmp", ".pdf"
        };

        public static bool IsPdfFilePath(string fileUrl)
        {
            var text = Path.GetExtension(fileUrl).ToLower();
            return ".pdf" == text;
        }

        public static bool IsNetworkImagePath(string filePath)
        {
            if (Uri.TryCreate(filePath, UriKind.Absolute, out Uri uri))
            {
                if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
                    return false;
                var extension = Path.GetExtension(uri.AbsolutePath);
                if (!IsFileTypeValid(extension))
                {
                    throw new TencentCloudApiException("文件类型错误");
                }
                return true;
            }
            return false;
        }


        public static async Task<byte[]> CheckFileTypeAndGetFileBytesAsync(string filePath, IServerCommandExecuteContext context)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new TencentCloudApiException("文件地址为空");
            }

            var extension = Path.GetExtension(filePath).ToLower();
            if (!IsFileTypeValid(extension))
            {
                throw new TencentCloudApiException("文件类型错误");
            }
            byte[] array;
            try
            {
                if (File.Exists(filePath))
                {
                    array = await File.ReadAllBytesAsync(filePath);
                }
                else
                {
                    array = await GetFileContentAsync(filePath, context);
                }

                if (array == null)
                {
                    throw new TencentCloudApiException("文件路径或者文件不存在");
                }
            }
            catch (ArgumentException ex)
            {
                throw new TencentCloudApiException(ex, "文件路径为空或者含有非法字符");
            }
            catch (PathTooLongException ex2)
            {
                throw new TencentCloudApiException(ex2, "文件路径过长");
            }
            catch (System.Exception ex3) when (ex3 is DirectoryNotFoundException || ex3 is FileNotFoundException)
            {
                throw new TencentCloudApiException(ex3, "文件路径或者文件不存在");
            }
            catch (System.Exception ex4)
            {
                throw new TencentCloudApiException(ex4, "读取路径出错");
            }

            CheckFileSize(array);
            return array;
        }

        private static void CheckFileSize(byte[] fileBytes)
        {
            if (fileBytes.Length > 7340032)
            {
                throw new TencentCloudApiException("文件过大");
            }
        }

        private static async Task<byte[]> GetFileContentAsync(string filePath, IServerCommandExecuteContext context)
        {
            var applicationAttachmentStorageInfo =
                ((context.ServiceProvider.GetService(typeof(IApplicationInformationService)) is
                    IApplicationInformationService service)
                    ? service.ApplicationAttachmentStorageInfo
                    : null);
            byte[] array;
            if (applicationAttachmentStorageInfo != null)
            {
                var file = applicationAttachmentStorageInfo.GetFilesFromAttachmentValue(filePath).First();
                array = await File.ReadAllBytesAsync(file);
            }
            else
            {
                array = null;
            }

            return array;
        }

        private static bool IsFileTypeValid(string fileExtension)
        {
            return !string.IsNullOrEmpty(fileExtension) && OcrFileExtensions.Contains(fileExtension);
        }
    }
}